//@flow
function sum(m: number, n: number) {
  return m + n;
}

sum(100, 100);
// sum('100', '100');

function square(n) {
  return n * n;
}

// 即使没有对参数类型做约束（也就是类型注解），通过类型推断也能发现错误
// square('100');

function foo(): number {
  // 类型注解不匹配
  // return '122'
  return 100;
}

// -----------原始类型
let name: string = 'foo';
let age: number = 30;
age = Infinity;
age = NaN;

const d: null = null;

const e: void = undefined;

const f: symbol = Symbol();

const g: boolean = true;

// 数组类型
const arr: Array<number> = [1, 2];

const arr1: number[] = [1, 2];

// 元组：固定长度的数组
const arr2: [string, number] = ['foo', 1];

// 对象类型
const obj: { foo: string, bar: number } = { foo: 'bar', bar: 1 };

const obj2: { foo: string, bar?: number } = { foo: 'bar' };

const obj3: { [string]: number } = { foo: 1 };

// 函数类型 参数类型和返回值的类型
function foo1(callback: (string, number) => void) {
  return callback('foo', 12);
}

// 特殊类型
// 字面量类型
const a: 'foo' = 'foo';
// 联合类型
const type: 'success' | 'warning' | 'danger' = 'success';

type StringOrNumber = string | number;
const aa: StringOrNumber = '123';

// maybe类型 在原来的类型上接受null和undefined
const gender: ?number = 22;

// mixed和any
// mixed类型是所有类型的混合
function passMixed(value: mixed) {
  if (typeof value === 'string') value.substring(0);

  if (typeof value === 'number') value * value;
}
passMixed('123');
passMixed(123);
passMixed(true);

// any也能够接受所有类型，但是any还是弱类型的
function passAny(value: any) {
  value.substring(0);
  value * value;
}

const element: HTMLElement | null = document.getElementById('app');
